package managers.strategy;

import managers.ElevatorManager;
import state.group.ElevatorStruct;
import state.group.GroupDispatcherState;
import state.group.HallCall;

public class DistanceStrategy extends HallCallStrategy {

	@Override
	public Byte assignHallCall(HallCall call) {
		
		byte minElevator = 0;
		byte minDistance = -1;
		
		GroupDispatcherState state = ElevatorManager.getInstance().getDispatcherState();
		
		synchronized (state.elevatorData)
		{
			if (state.elevatorData.size() == 0)
			{
				return 0;
			}
			
			if (state.elevatorData.size() == 1)
			{
				for (Byte b : state.elevatorData.keySet())
				{
					return b;
				}
			}
			
			for (ElevatorStruct s : state.elevatorData.values())
			{
				if (minElevator == 0)
				{
					minElevator = s.identifier;
					
					minDistance = evalDistance(call, s);
					
				}
				else
				{
					byte distance = evalDistance(call, s);
					
					if (distance < minDistance)
					{
						minElevator = s.identifier;
						
						minDistance = distance;
					}
				}
			}
		}
		
		return minElevator;
	}
	
	private byte evalDistance(HallCall call, ElevatorStruct struct)
	{
		byte floorCount = ElevatorManager.getInstance().getDispatcherState().maxFloors;
		if (call.getDirection() == 1)
		{
			if (struct.direction == 1)
			{
				if (struct.lastKnownFloor > call.getFloor())
				{
					return (byte) (2 * floorCount - struct.lastKnownFloor - call.getFloor());
				}
				else
				{
					return (byte) (call.getFloor() - struct.lastKnownFloor);
				}
			}
			else
			{
				return (byte) (struct.lastKnownFloor + call.getFloor());
			}
		}
		else
		{
			if (struct.direction == 1)
			{
				return (byte) (2 * floorCount - struct.lastKnownFloor - call.getFloor());
			}
			else
			{
				if (struct.lastKnownFloor < call.getFloor())
				{
					return (byte) (struct.lastKnownFloor + call.getFloor());
				}
				else
				{
					return (byte) (struct.lastKnownFloor - call.getFloor());
				}
			}
		}
	}

	@Override
	public void resolveHallCall(HallCall call) {
		
	}

	@Override
	public void verifyHallCalls() {
		
	}
	
}
